package dslab.transfer;

import java.util.concurrent.BlockingQueue;

/**
 * transfer specific utility class that is runnable and should run in its own thread;
 * the purpose is to process outbound send tasks in an orderly fashion
 */
public class SendQueueHandler implements Runnable {

    private final String componentId;
    private final BlockingQueue<Runnable> outboundSendTasks;

    /**
     * creates a new SendQueueHandler
     * @param componentId string representation of component
     * @param outboundSendTasks queue where outbound send tasks will be put to, should already be initialized
     */
    public SendQueueHandler(String componentId, BlockingQueue<Runnable> outboundSendTasks) {
        // queue has to be initialized
        if (outboundSendTasks == null)
            throw new IllegalArgumentException();

        this.componentId = componentId;
        this.outboundSendTasks = outboundSendTasks;
    }

    @Override
    public void run() {
        System.out.printf("@%s: begin run%n", componentId);
        try {
            while (true) {
                // BlockingQueue is battle-tested and thread-safe
                outboundSendTasks.take().run();
                System.out.printf("@%s: done sending message%n", componentId);
            }
        } catch (InterruptedException exception) {
            System.out.printf("@%s: stopped execution due to interruption%n", componentId);
        }
        System.out.printf("@%s: end run%n", componentId);
    }
}
